/****************************************************************************
 * Copyright (c) 2008, 2010 Andreas Unger and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Andreas Unger - initial API and implementation 
 ****************************************************************************/

package org.eclipselabs.damos.diagram.ui.internal.properties;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.eclipse.emf.ecore.EObject;
import org.eclipselabs.damos.diagram.ui.properties.AbstractComboPropertySection;
import org.eclipselabs.damos.dml.Component;
import org.eclipselabs.damos.dml.DMLFactory;
import org.eclipselabs.damos.dml.DataKind;
import org.eclipselabs.damos.dml.DataType;
import org.eclipselabs.damos.dml.ExplicitOutputDataTypeSpecification;
import org.eclipselabs.damos.dml.Output;
import org.eclipselabs.damos.dml.OutputDataTypeSpecification;
import org.eclipselabs.damos.expressions.util.ExpressionsUtil;

/**
 * @author Andreas Unger
 *
 */
public class OutputDataTypePropertySection extends AbstractComboPropertySection {
	
	private static final List<String> PROPERTY_VALUE_STRINGS_SCALAR = Arrays.asList(new String[] {
			"Inherit",
			"double",
			"Q1.15",
			"Q1.31"});

	private static final List<String> PROPERTY_VALUE_STRINGS_MIXED = Arrays.asList(new String[] {
			"Inherit",
			"boolean",
			"double",
			"Q1.15",
			"Q1.31"});

	private boolean propertyValueStringsChanged = true;
	
	/* (non-Javadoc)
	 * @see org.eclipselabs.damos.diagram.ui.properties.AbstractComboPropertySection#getPropertyChangeCommandName()
	 */
	protected String getPropertyChangeCommandName() {
		return "Change Output Data Type";
	}

	/* (non-Javadoc)
	 * @see org.eclipselabs.damos.diagram.ui.properties.AbstractComboPropertySection#getPropertyNameLabel()
	 */
	protected String getPropertyNameLabel() {
		return "Output Data Type:";
	}
	
	/* (non-Javadoc)
	 * @see org.eclipselabs.damos.diagram.ui.properties.AbstractComboPropertySection#isEditable()
	 */
	protected boolean isEditable() {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.eclipselabs.damos.diagram.ui.properties.AbstractComboPropertySection#getPropertyValue()
	 */
	protected String getPropertyValue() {
		DataType dataType = getOutputDataType();
		if (dataType != null) {
			return ExpressionsUtil.dataTypeToString(dataType);
		}
		return "";
	}
	
	/* (non-Javadoc)
	 * @see org.eclipselabs.damos.diagram.ui.properties.AbstractComboPropertySection#getPropertyValueIndex()
	 */
	protected int getPropertyValueIndex() {
		DataType dataType = getOutputDataType();
		if (dataType != null) {
			return getPropertyValueStrings().indexOf(ExpressionsUtil.dataTypeToString(dataType));
		}
		return 0;
	}

	/* (non-Javadoc)
	 * @see org.eclipselabs.damos.diagram.ui.properties.AbstractComboPropertySection#getPropertyValueStrings()
	 */
	protected List<String> getPropertyValueStrings() {
		DataKind dataKind = getOutputDataKind();
		if (dataKind != null) {
			switch (getOutputDataKind()) {
			case SCALAR:
				return PROPERTY_VALUE_STRINGS_SCALAR;
			case MIXED:
				return PROPERTY_VALUE_STRINGS_MIXED;
			}
		}
		return Collections.emptyList();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipselabs.damos.diagram.ui.properties.AbstractComboPropertySection#propertyValueStringsChanged()
	 */
	protected boolean propertyValueStringsChanged() {
		if (propertyValueStringsChanged) {
			propertyValueStringsChanged = false;
			return true;
		}
		return false;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipselabs.damos.diagram.ui.properties.AbstractComboPropertySection#setPropertyValue(org.eclipse.emf.ecore.EObject, java.lang.Object)
	 */
	protected void setPropertyValue(EObject object, Object value) {
		if (object instanceof Component) {
			Component component = (Component) object;
			DataType dataType = ExpressionsUtil.parseDataTypeExpression((String) value);
			ExplicitOutputDataTypeSpecification spec = null;
			if (dataType != null) {
				spec = DMLFactory.eINSTANCE.createExplicitOutputDataTypeSpecification();
				spec.setDataType(dataType);
			}
			component.setOutputDataTypeSpecification(spec);
		}
	}
	
	private DataType getOutputDataType() {
		Component component = getComponent();
		if (component != null) {
			OutputDataTypeSpecification spec = component.getOutputDataTypeSpecification();
			if (spec instanceof ExplicitOutputDataTypeSpecification) {
				return ((ExplicitOutputDataTypeSpecification) spec).getDataType();
			}
		}
		return null;
	}
	
	private DataKind getOutputDataKind() {
		Component component = getComponent();
		if (component != null) {
			List<Output> outputs = component.getOutputs();
			if (!outputs.isEmpty()) {
				return outputs.get(0).getDataKind();
			}
		}
		return null;
	}
	
	private Component getComponent() {
		EObject element = getEObject();
		if (element instanceof Component) {
			return (Component) element;
		}
		return null;
	}

}
